#include <stdlib.h>
#include <stdio.h>
#include <omp.h>

void userBinaryOperator(void *input1andOutput, void *input2);

#define ubop(x1,x2) userBinaryOperator( (void *) (x1), (void *) (x2) );

void genericScan(void *X, int n, size_t l)
{

	int i;
	char *c = (char *)X;

	for (i=1;i<n;i++)	
		ubop( c+i*l,  c+l*(i-1) ); 
}

void genericScanParallel(void *X, int n, size_t l)
{

        int i, j;
	char *c = (char *)X;
	int nts = 0;

	#pragma omp parallel
	{
	  nts = omp_get_num_threads();
	}

	int blk_size = n/nts;
	int m = 0;
	printf("%i\n", nts);

	/*
	  See the following document 21.2.4 for idea
	  http://www.cs.wisc.edu/~tvrdik/21/ps/Section21.ps	
	*/

	//Step 1: Do local scan in parallel requires O(n/p)
	for( i=0; i<nts; i++)
	  {
	    m = blk_size;
	    //Y = X + i * m * l;
	    genericScan(c, m, l);
	    c += m*l;
	    printf("%i\n", m);
	  }

	//Step 2: Do global scan on the last elements 
	//from the local arrays on the master thread

	//Step 3: Do local sum in parallel
	
}

